//负责编译事件字符串并且绑定事件处理函数
import {
  checkType,
  randomNum
} from "../shared/utils";

const
  //匹配()里面的内容
  //规则：任意字符1次或多次非贪婪
  reg_onClick = /onClick\=\"(.+?)\"/g,
  //匹配以在反括号 ( 之前的内容 
  //如 add(2) 里面的 add 名称
  //规则: 以任意字符1次或多次非贪婪
  reg_fnName = /^(.+?)\(/,
  //匹配()里的内容
  //如 add(2) 里面的 2 
  //规则：以任意字符0次或多次非贪婪
  reg_arg = /\((.*?)\)/,
  eventPool = [];

/**
 * 处理template里面的事件格式
 * 如：<button onClilck="minus(1)">
 * @param {*} template 未处理的字符串模板
 * @returns 处理好的字符串模板
 * 
 * 希望的数据结构
 * @mark 表示唯一的当前的dom，通过标识找到当前的dom
 * @handler 通过handler绑定事件处理函数
 * @type 事件的类型
 * eventPool = [
 *   {
 *     mark: random,
 *     handler: 事件处理函数的字符串,
 *     type: 'click'
 *   }
 * ]
 */
export function eventFormat(template) {
  /**
   * console.log(template.match(reg_onClick));
   * [
   *   "onClick=\"add(2)\"", 
   *   "onClick=\"minus(1)\"", 
   *   "onClick=\"changeName('大田')\""
   * ]
   */

  return template.replace(reg_onClick, function (node, key) {
    // console.log(node); onClick="add(2)"
    // console.log(key); add(2)
    const _mark = randomNum();

    eventPool.push({
      mark: _mark,
      handler: key.trim(),
      type: 'click'
    });

    /**
     * console.log(eventPool):
     * [
     *   {mark: 1628084641347, handler: "add(2)", type: "click"},
     *   {mark: 1628084642629, handler: "minus(1)", type: "click"},
     *   {mark: 1628084638933, handler: "changeName('大田')", type: "click"}
     * ]
     */

    //如何替换<button onClick="add(2)">里面的onClick="add(2)" ?
    //答案：直接替换node内容
    //console.log(`data-mark="${_mark}"`); data-mark="1628085068437"
    return `data-mark="${_mark}"`;
  });
}

/**
 * 绑定事件
 * @param {*} methods 一个方法对象，如{add, minus, changeName}
 * @return 
 */
export function bindEvent(methods) {
  //获取所有的元素节点
  const allElements = document.querySelectorAll('*');
  let
    oItem = null,
    _mark = 0;

  eventPool.forEach(event => {
    for (let i = 0; i < allElements.length; i++) {
      oItem = allElements[i];

      _mark = parseInt(oItem.dataset.mark);
      // console.log(_mark); 1628085068437
      if (event.mark === _mark) {
        //绑定事件处理函数
        oItem.addEventListener(event.type, function () {
          //找到函数名称
          const
            fnName = event.handler.match(reg_fnName)[1],
            //console.log(fnName); 
            //["add(", "add", index: 0, input: "add(2)", groups: undefined]
            //判断arg的第一项是否带有''/""
            arg = checkType(event.handler.match(reg_arg)[1]);
          //console.log(arg);
          //["(2)", "2", index: 3, input: "add(2)", groups: undefined]

          //执行方法
          //如 add(2) / minus(1) /changeName('大田')
          methods[fnName](arg);
        }, false);

      }
    }
  })
}